//
//  Matrix.m
//  Philippe
//
//  Created by Maximilien Servajean on 04/05/14.
//  Copyright (c) 2014 Maximilien Servajean. All rights reserved.
//

#import "Matrix.h"

@implementation Matrix

@synthesize singleLineSize;

- (id) initWithSize:(NSInteger)size {
    if(self = [super init]) {
        self.singleLineSize = size;
        linesArray = [[NSMutableArray alloc] init];
        activationArray = [[NSMutableArray alloc] init];
        similarityArray = [[NSMutableArray alloc] init];
        
        ponderation = [[ActivationPonderation alloc]init];
    }
    return self;
}

- (id) init {
    if(self = [super init]) {
        self.singleLineSize = -1;
        linesArray = [[NSMutableArray alloc] init];
        activationArray = [[NSMutableArray alloc] init];
        similarityArray = [[NSMutableArray alloc] init];
        echo = [[NSMutableArray alloc] init];
        ponderation = [[ActivationPonderation alloc]init];
    }
    return self;
}

- (BOOL) addSonde:(NSArray*)line {
    if([linesArray count]==0){
        [self setSingleLineSize:[line count]];
    } else if ([line count]!=[self singleLineSize]){
        NSLog(@"La sonde ne respecte pas la taille souhaitée...");
        return NO;
    }
    
    [self computeSimilarityWith:line];
    
    
    
    
    [linesArray addObject:line];
    [similarityArray addObject:@(0)];
    [activationArray addObject:@(0)];
    [self computeEcho];
    if([self saveEcho]) {
        [linesArray addObject:echo];
        [similarityArray addObject:@(0)];
        [activationArray addObject:@(0)];
    }
    return YES;
}

- (void) computeSimilarityWith:(NSArray*)sonde {
   for (NSInteger i = 0; i < [linesArray count]; ++i) {
        NSArray* line = [linesArray objectAtIndex:i];
        if([sonde count] == [line count]) {
            NSNumber *similarity = 0;
            NSNumber *denominateur = 0;
            for (NSInteger j = 0 ; j < [line count] ; j++) {
                NSNumber *sondeNum = [sonde objectAtIndex:j];
                NSNumber *lineNum = [line objectAtIndex:j];
                similarity=@([sondeNum floatValue]*[lineNum floatValue]+[similarity floatValue]);
                
                // ON prend la valeur absolue
                if([lineNum floatValue]<0)
                    denominateur=@(-[lineNum floatValue]+[denominateur floatValue]);
                else
                    denominateur=@([lineNum floatValue]+[denominateur floatValue]);
            }

            similarity = @([similarity floatValue]/[denominateur floatValue]);
            [similarityArray setObject:similarity atIndexedSubscript:i];
            
            NSNumber* activation = @([ponderation ponderationPourLigne:i etTaille:[linesArray count]]*[similarity floatValue]);
            [activationArray setObject:activation atIndexedSubscript:i];
        } else {
            NSLog(@"La taille de la sonde est differente de la taille d'une ligne de la matrice...");
        }
    }
}

- (void) computeEcho {
    echo = [[NSMutableArray alloc]init];
    NSNumber *sum = 0;
    for (NSInteger i = 0; i < [linesArray count]; ++i) {
        NSArray* line = [linesArray objectAtIndex:i];
            for (NSInteger j = 0 ; j < [line count] ; j++) {
                NSNumber* echoVal;
                if([echo count]<=j) {
                    echoVal = 0;
                } else {
                    echoVal = [NSNumber numberWithDouble:[echo objectAtIndex:j]!=nil?[[echo objectAtIndex:j]floatValue]:0];
                }
                
//                ++if ([[activationArray objectAtIndex:i]floatValue]>=0) {
                    echoVal = @([echoVal floatValue]+[[line objectAtIndex:j]floatValue]*[[activationArray objectAtIndex:i]floatValue]);
  //              } else {
    //                echoVal = @([echoVal floatValue]+[[line objectAtIndex:j]floatValue]*(-1)*[[activationArray objectAtIndex:i]floatValue]);
      //          }
                
                
                [echo setObject:echoVal atIndexedSubscript:j];
            }
        if([[activationArray objectAtIndex:i]floatValue]>=0)
            sum = @([sum floatValue]+[[activationArray objectAtIndex:i]floatValue]);
        else
            sum = @([sum floatValue]-[[activationArray objectAtIndex:i]floatValue]);
    }
    if([sum floatValue]!= 0 )
        for(NSInteger i = 0 ; i < [echo count] ; i++) {
            NSNumber *current = [echo objectAtIndex:i];
            current = @([current floatValue]/[sum floatValue]);
            [echo setObject:current atIndexedSubscript:i];
        }
}



- (void) clear {
    [linesArray removeAllObjects];
    [activationArray removeAllObjects];
    [similarityArray removeAllObjects];
}

- (NSString*) activationString {
    NSString* result = @"";
    for(NSInteger i = 0 ; i < [activationArray count] ; i++){
        if ([result isEqualToString:@""]) {
            result = [result stringByAppendingFormat:@"l.%ld: %@",(i+1),[activationArray objectAtIndex:i]];
        } else {
            result = [result stringByAppendingFormat:@"\nl.%ld: %@",(i+1),[activationArray objectAtIndex:i]];
        }
    }
    return result;
}

- (NSString*) echoString {
    NSString* result = @"";
    for(NSInteger i = 0 ; i < [echo count] ; i++){
        if ([result isEqualToString:@""]) {
            result = [result stringByAppendingFormat:@"%@",[echo objectAtIndex:i]];
        } else {
            result = [result stringByAppendingFormat:@";%@",[echo objectAtIndex:i]];
        }
    }
    return result;
}

- (NSString*) matriceString {
    NSString* result =@"";
    for (NSInteger i = 0; i < [linesArray count]; i++) {
        if (i>0) {
            result = [result stringByAppendingString:@"\n"];
        }
        NSArray* line = [linesArray objectAtIndex:i];
        for (NSInteger j = 0; j < [line count]; j++) {
            if(j>0)
                result = [result stringByAppendingFormat:@";%@",[line objectAtIndex:j]];
            else
                result = [result stringByAppendingFormat:@"l.%ld: %@",(i+1),[line objectAtIndex:j]];
        }
    }
    return result;
}

- (NSString*) similarityString {
    NSString* result = @"";
    for(NSInteger i = 0 ; i < [similarityArray count] ; i++){
        if ([result isEqualToString:@""]) {
            result = [result stringByAppendingFormat:@"l.%ld: %@",(i+1),[similarityArray objectAtIndex:i]];
        } else {
            result = [result stringByAppendingFormat:@"\nl.%ld: %@",(i+1),[similarityArray objectAtIndex:i]];
        }
    }
    return result;
}

- (BOOL) saveEcho {
    BOOL result = NO;
    NSInteger i = 0;
    while (i < [echo count] && !result){
        if ([[echo objectAtIndex:i]floatValue]!=0){
            result = YES;
        } else {
            i++;
        }
    }
    return result;
}
@end
